// Projective texturing vertex shader
// Can be used in all shading models

uniform vec3 fvR;
uniform vec3 fvP;
uniform vec3 fvTp;
uniform float fAlpha;
uniform float fAspect;
uniform vec3 fvEyePosition;

varying vec2 Texcoord;
varying vec4 ProjTexcoord;
varying vec3 ViewDirection;
varying vec3 LightDirection;
varying float Distance;
varying float NDotP;

attribute vec3 rm_Binormal;
attribute vec3 rm_Tangent;

void main( void )
{
   gl_Position = ftransform();
   Texcoord    = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
    
   vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
   
   vec3 fvViewDirection  = fvEyePosition - fvObjectPosition.xyz;
   vec3 fvLightDirection = gl_LightSource[0].position.xyz - fvObjectPosition.xyz;
   
   vec3 fvNormal         = gl_NormalMatrix * gl_Normal;
   vec3 fvBinormal       = gl_NormalMatrix * rm_Binormal;
   vec3 fvTangent        = gl_NormalMatrix * rm_Tangent;
   
   Distance         = distance( gl_LightSource[0].position.xyz, fvObjectPosition.xyz );
      
   ViewDirection.x  = dot( fvTangent, fvViewDirection );
   ViewDirection.y  = dot( fvBinormal, fvViewDirection );
   ViewDirection.z  = dot( fvNormal, fvViewDirection );
   
   LightDirection.x  = dot( fvTangent, fvLightDirection.xyz );
   LightDirection.y  = dot( fvBinormal, fvLightDirection.xyz );
   LightDirection.z  = dot( fvNormal, fvLightDirection.xyz );
    
   vec3 fvRn = normalize( fvR );
   vec3 fvTpn = normalize( fvTp );
   vec3 fvSn = normalize( cross( fvRn, fvTpn ) );
   vec3 fvTn = normalize( cross( fvSn , fvRn ) );
    
   mat4 fmVp = mat4( 
             vec4(fvSn.x, fvTn.x, fvRn.x, 0.0),
             vec4(fvSn.y, fvTn.y, fvRn.y, 0.0),
             vec4(fvSn.z, fvTn.z, fvRn.z, 0.0),
             vec4(dot( -fvSn, fvP ), 
                  dot( -fvTn, fvP ),
                  dot( -fvRn, fvP ), 1.0)
   );
    
   float e = 1.0 / tan( fAlpha * 0.5 );
    
   mat4 fmPp = mat4(
             vec4(e * 0.5, 0.0, 0.0, 0.0),
             vec4(0.0, e / (2.0 * fAspect), 0.0, 0.0),
             vec4(0.5, 0.5, 0.0, 1.0),
             vec4(0.0, 0.0, 0.0, 0.0)
   );
   
   ProjTexcoord = gl_TextureMatrix[1] * fmPp * fmVp * gl_Vertex;
   NDotP = max( 0.0, dot( normalize( gl_Normal ), normalize( fvP - gl_Vertex.xyz ) ) );
}
